package config

import (
	"encoding/json"
	"fmt"
	"os"
	"path/filepath"

	"gopkg.in/yaml.v3"
)

// Config 配置结构
type Config struct {
	Auth      AuthConfig      `json:"auth" yaml:"auth"`
	Whitelist WhitelistConfig `json:"whitelist" yaml:"whitelist"`
	Proxies   []ProxyConfig   `json:"proxies" yaml:"proxies"`
}

// AuthConfig 认证服务配置
type AuthConfig struct {
	ListenPort string `json:"listen_port" yaml:"listen_port"`
	Secret     string `json:"secret" yaml:"secret"`
	Path       string `json:"path" yaml:"path"`
}

// WhitelistConfig 白名单配置
type WhitelistConfig struct {
	Expiration int `json:"expiration" yaml:"expiration"` // 白名单有效期（秒）
}

// ProxyConfig 代理服务配置
type ProxyConfig struct {
	Name       string `json:"name" yaml:"name"`
	ListenPort string `json:"listen_port" yaml:"listen_port"`
	TargetPort string `json:"target_port" yaml:"target_port"`
}

// NewDefaultConfig 创建默认配置
func NewDefaultConfig() *Config {
	return &Config{
		Auth: AuthConfig{
			ListenPort: ":4567",
			Secret:     "hello",
			Path:       "/auth",
		},
		Whitelist: WhitelistConfig{
			Expiration: 3600, // 默认1小时
		},
		Proxies: []ProxyConfig{
			{
				Name:       "ssh",
				ListenPort: ":10022",
				TargetPort: "127.0.0.1:22",
			},
			{
				Name:       "web",
				ListenPort: ":8080",
				TargetPort: "localhost:80",
			},
			{
				Name:       "mysql",
				ListenPort: ":3306",
				TargetPort: "localhost:3306",
			},
		},
	}
}

// LoadFromFile 从文件加载配置
func LoadFromFile(path string) (*Config, error) {
	data, err := os.ReadFile(path)
	if err != nil {
		return nil, err
	}

	cfg := &Config{}
	ext := filepath.Ext(path)
	switch ext {
	case ".json":
		if err := json.Unmarshal(data, cfg); err != nil {
			return nil, err
		}
	case ".yaml", ".yml":
		if err := yaml.Unmarshal(data, cfg); err != nil {
			return nil, err
		}
	default:
		return nil, fmt.Errorf("unsupported config file format: %s", ext)
	}

	return cfg, nil
}

// SaveToFile 保存配置到文件
func (c *Config) SaveToFile(path string) error {
	var data []byte
	var err error

	ext := filepath.Ext(path)
	switch ext {
	case ".json":
		data, err = json.MarshalIndent(c, "", "  ")
	case ".yaml", ".yml":
		data, err = yaml.Marshal(c)
	default:
		return fmt.Errorf("unsupported config file format: %s", ext)
	}

	if err != nil {
		return err
	}

	return os.WriteFile(path, data, 0644)
}
